﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZRFCore.Camera;
using HalconDotNet;
using ZRFCore.MachineVisionAlgorithm.Controls.ZrfWindowControl.Model;
using ZRFCore.MachineVisionAlgorithm.Controls.ZrfWindowControl;
using ZRFCore.MachineVisionAlgorithm.ShapeMatching;
using ZRFCore.MachineVisionAlgorithm.DefectDetection;
using ZRFCore.Tool;
using ZRFCore.MachineVisionAlgorithm.VisionTools;
using System.IO;
using System.Threading;
using ZRFCore.MachineVisionAlgorithm.Controls.ZrfWindowControl.Path;
using ZRFCore.MachineVisionAlgorithm.Calibration2D;
using MultiAxisAssembly.Motion;
using ZRFCore.MotionControlCard;
using ZRFCore.MachineVisionAlgorithm.Controls.ZrfWindowControl.Object;

namespace MultiAxisAssembly
{
    [Serializable]
    public class ControlMaster
    {
        public ICamera Camera;
        public MachinePro MachineProEx { get { return machinePro; } }
        private MachinePro machinePro;
        public HImage? StandardImg { get { return projFile.StandardImg?.Clone(); } set { projFile.StandardImg = value?.Clone(); SetSnapPos(); } }
        public ShapeMatching ShapeMatching { get { return projFile.ShapeMatching; } }
        public List<IROI> ShapeModelRois { get { return projFile.ShapeModelRois; } set { projFile.ShapeModelRois = value; } }
        public List<XldPath> XldPaths { get { return projFile.XldPaths; } set { projFile.XldPaths = value; } }
        public List<HRegionWithColor> XldPathRegions { get { return projFile.XldPathRegions; } set { projFile.XldPathRegions = value; } }
        public List<XldPathInfo> XldPathInfos { get { return projFile.XldPathInfos; } }
        private ICalibration2D Calibration;
        /// <summary>
        /// 启动项目时的事件
        /// </summary>
        public event StartProjWorkEventHandler? StartProjWorkEvent;
        public event FindedProjAllXldPathsEventHandler? FindedProjAllXldPathsEvent;
        private string CamParamerPath = Directory.GetCurrentDirectory() + "/Calib/CamParamer";
        private string CamPosPath = Directory.GetCurrentDirectory() + "/Calib/CamPos";
        private string HomMat2DPath = Directory.GetCurrentDirectory() + "/Calib/HomMat2D";
        private string SystemParamerPath = Directory.GetCurrentDirectory() + "/SysParameter.xml";
        private string CalibXPosPath = Directory.GetCurrentDirectory() + "/Calib/XPos.tup";
        private string CalibYPosPath = Directory.GetCurrentDirectory() + "/Calib/YPos.tup";
        private string CalibZPosPath = Directory.GetCurrentDirectory() + "/Calib/ZPos.tup";

        /// <summary>
        /// 拍照位置X
        /// </summary>
        public float SnapPosX { get { return projFile.SnapPosX; } }
        /// <summary>
        /// 拍照位置Y
        /// </summary>
        public float SnapPosY { get { return projFile.SnapPosY; } }
        /// <summary>
        /// 拍照位置Z
        /// </summary>
        public float SnapPosZ { get { return projFile.SnapPosZ; } }

        public double CalibPosX { get { return Calibration.CalibSnapMachX; } }
        public double CalibPosY { get { return Calibration.CalibSnapMachY; } }
        public double CalibPosZ { get { return Calibration.CalibSnapMachZ; } }
        private ProjFile projFile;
        private string projName = "";
        public string ProjName { get { return projName; } }
        private SysParameter _sysParameter = new SysParameter();
        private bool readyWholeWork = false;
        private bool isIntoIoTable = false;
        public bool IsSpurtGlue = true;
        private bool isDoProjWork = false;//正在执行工程动作


        //参数
        public int SpurtGlueWidth = 50;
        public int GlueWidth = 10;
        public float EmptyMoveSpeed { get { return machinePro.EmptyMoveSpeed; } set { machinePro.EmptyMoveSpeed = value; } }

        //点胶默认参数
        public float GlueClosePlaneZpos = 36.6568f;//点胶头贴板Z位置
        public float GlueHeadDeviationX = 0;//点胶头偏差X
        public float GlueHeadDeviationY = 0;//点胶头偏差Y
        public float GlueDefaultHeight = 5;//点胶默认高度

        //喷胶默认参数
        public float SpurtGlueClosePlaneZpos = 20;//喷胶头贴板Z位置
        public float SpurtGlueHeadDeviationX = 20;//喷胶头偏差X
        public float SpurtGlueHeadDeviationY = 20;//喷胶头偏差Y
        public float SpurtGlueDefaultHeight = 25;//喷胶默认高度

        public double ZSafePos { get { return machinePro.ZSafePos; } set { machinePro.ZSafePos = value; } }

        #region 生产报表数据
        public int ProductionQuantity { get { return _productionQuantity; } }
        private int _productionQuantity = 0;
        #endregion

        #region 系统参数
        [Serializable]
        public class SysParameter
        {
            public int SpurtGlueWidth = 50;
            public int GlueWidth = 10;
            public float EmptyMoveSpeed = 500;

            //点胶默认参数
            public float GlueClosePlaneZpos = 36.6568f;//点胶头贴板Z位置
            public float GlueHeadDeviationX = 0;//点胶头偏差X
            public float GlueHeadDeviationY = 0;//点胶头偏差Y
            public float GlueDefaultHeight = 5;//点胶默认高度

            //喷胶默认参数
            public float SpurtGlueClosePlaneZpos = 20;
            public float SpurtGlueHeadDeviationX = 20;//喷胶头偏差X
            public float SpurtGlueHeadDeviationY = 20;//喷胶头偏差Y
            public float SpurtGlueDefaultHeight = 25;//喷胶默认高度

            /// <summary>
            /// 标定拍照位X
            /// </summary>
            public double CalibSnapMachX = 0;

            /// <summary>
            /// 标定拍照位Y
            /// </summary>
            public double CalibSnapMachY = 0;

            /// <summary>
            /// 标定拍照位Z
            /// </summary>
            public double CalibSnapMachZ = 0;

            /// <summary>
            /// 标定拍照位R
            /// </summary>
            public double CalibSnapMachR = 0;

            public double ZSafePos = 0;
        }

        /// <summary>
        /// 读取系统参数
        /// </summary>
        private void ReadSysParameter()
        {
            SysParameter? _sysParameter = ParameterHelper.GetParamFromFile<SysParameter>(SystemParamerPath);
            if (_sysParameter != null)
            {
                SpurtGlueWidth = _sysParameter.SpurtGlueWidth;
                GlueWidth = _sysParameter.GlueWidth;
                EmptyMoveSpeed = _sysParameter.EmptyMoveSpeed;

                //点胶默认参数
                GlueClosePlaneZpos = _sysParameter.GlueClosePlaneZpos;//点胶头贴板Z位置
                GlueHeadDeviationX = _sysParameter.GlueHeadDeviationX;//点胶头偏差X
                GlueHeadDeviationY = _sysParameter.GlueHeadDeviationY;//点胶头偏差Y
                GlueDefaultHeight = _sysParameter.GlueDefaultHeight;//点胶默认高度

                //喷胶默认参数
                SpurtGlueClosePlaneZpos = _sysParameter.SpurtGlueClosePlaneZpos;
                SpurtGlueHeadDeviationX = _sysParameter.SpurtGlueHeadDeviationX;//喷胶头偏差X
                SpurtGlueHeadDeviationY = _sysParameter.SpurtGlueHeadDeviationY;//喷胶头偏差Y
                SpurtGlueDefaultHeight = _sysParameter.SpurtGlueDefaultHeight;//喷胶默认高度

                ZSafePos = _sysParameter.ZSafePos;

                //标定机械坐标
                Calibration.CalibSnapMachX = _sysParameter.CalibSnapMachX;
                Calibration.CalibSnapMachY = _sysParameter.CalibSnapMachY;
                Calibration.CalibSnapMachZ = _sysParameter.CalibSnapMachZ;
                Calibration.CalibSnapMachR = _sysParameter.CalibSnapMachR;


            }
        }

        /// <summary>
        /// 保存系统参数
        /// </summary>
        private void SaveSysParameter()
        {
            _sysParameter.SpurtGlueWidth = SpurtGlueWidth;
            _sysParameter.GlueWidth = GlueWidth;
            _sysParameter.EmptyMoveSpeed = EmptyMoveSpeed;

            //点胶默认参数
            _sysParameter.GlueClosePlaneZpos = GlueClosePlaneZpos;//点胶头贴板Z位置
            _sysParameter.GlueHeadDeviationX = GlueHeadDeviationX;//点胶头偏差X
            _sysParameter.GlueHeadDeviationY = GlueHeadDeviationY;//点胶头偏差Y
            _sysParameter.GlueDefaultHeight = GlueDefaultHeight;//点胶默认高度

            //喷胶默认参数
            _sysParameter.SpurtGlueClosePlaneZpos = SpurtGlueClosePlaneZpos;
            _sysParameter.SpurtGlueHeadDeviationX = SpurtGlueHeadDeviationX;//喷胶头偏差X
            _sysParameter.SpurtGlueHeadDeviationY = SpurtGlueHeadDeviationY;//喷胶头偏差Y
            _sysParameter.SpurtGlueDefaultHeight = SpurtGlueDefaultHeight;//喷胶默认高度

            _sysParameter.ZSafePos = ZSafePos;

            //标定机械坐标
            _sysParameter.CalibSnapMachX = Calibration.CalibSnapMachX;
            _sysParameter.CalibSnapMachY = Calibration.CalibSnapMachY;
            _sysParameter.CalibSnapMachZ = Calibration.CalibSnapMachZ;
            _sysParameter.CalibSnapMachR = Calibration.CalibSnapMachR;

            ParameterHelper.SaveParam(_sysParameter, SystemParamerPath);
        }
        #endregion

        public MulitAxisMaster MulitAxisMasterControl;//多轴控制器
        public float XAxisDPos { get { return machinePro.XAxis.DPos; } }
        public float YAxisDPos { get { return machinePro.YAxis.DPos; } }
        public float ZAxisDPos { get { return machinePro.ZAxis.DPos; } }
        public float Speed { get { return machinePro.Speed; } }
        public IInput[] Inputs { get { return machinePro.Inputs; } }
        public IOutput[] Outputs { get { return machinePro.Outputs; } }
        public bool MachineIsEmergentStop { get { return machinePro.MotionStatus.IsEmergentStop; } }
        public void AllAxisHoming()
        {
            machinePro.AllAxisesHoming();
        }

        #region Proj
        [Serializable]
        public class ProjFile
        {
            /// <summary>
            /// 拍照位置X
            /// </summary>
            internal float SnapPosX { get; set; }
            /// <summary>
            /// 拍照位置Y
            /// </summary>
            internal float SnapPosY { get; set; }
            /// <summary>
            /// 拍照位置Z
            /// </summary>
            internal float SnapPosZ { get; set; }
            /// <summary>
            /// 工程图片
            /// </summary>
            internal HImage? StandardImg { get { return standardImg?.Clone(); } set { standardImg = value?.Clone(); } }
            private HImage? standardImg;
            internal ShapeMatching ShapeMatching = new ShapeMatching();
            internal List<IROI> ShapeModelRois = new List<IROI>();
            internal List<XldPath> XldPaths = new List<XldPath>();
            internal List<HRegionWithColor> XldPathRegions = new List<HRegionWithColor>();
            internal List<XldPathInfo> XldPathInfos = new List<XldPathInfo>();
            public void Dispose()
            {
                StandardImg?.Dispose();
            }
        }

        public string ReadProj()
        {
            projFile = FileHelper.LoadFileDialog<ProjFile>("点胶方案(*.glue)|*.glue", out projName, out _);
            _productionQuantity = 0;
            return projName;
        }

        public string SaveProj()
        {
            FileHelper.SaveFileDialog(projFile, "点胶方案(*.glue)|*.glue", out projName, out _);
            return projName;
        }

        #endregion

        /// <summary>
        /// 准备全局工作
        /// </summary>
        public void ReadyToWork()
        {
            try
            {
                Camera.TrigSource = TrigSource.SoftTrig;
                Camera.StartGrabbing();
            }
            catch (Exception)
            {
                throw;
            }
            readyWholeWork = true;
        }

        /// <summary>
        /// 结束全局工作
        /// </summary>
        public void EndReadyToWork()
        {
            readyWholeWork = false;
        }

        private void In_StartPauseButton_EnableEvent(IInput sender, InputEventArgs e)
        {
            try
            {
                if (readyWholeWork == true)
                {
                    if (isDoProjWork == false)//没有在执行项目工作
                    {
                        DoProjWork();
                    }
                    else
                    {
                        //PauseResumeProjWork();
                    }
                }
            }
            catch (Exception ee)
            {
                Dialog.ShowWarningDialog(ee.Message);
            }
        }

        bool isRest = false;
        private void In_ResetButton_EnableEvent(IInput sender, InputEventArgs e)
        {
            if (isRest == true)
            {
                return;
            }
            isRest = true;
            Task.Run(() =>
            {
                machinePro.Reset();
                isRest = false;
            });
        }

        public void FormIntoIoTable()
        {
            isIntoIoTable = true;
        }

        public void FormExitIoTable()
        {
            isIntoIoTable = false;
            machinePro.Out_PointGlueControl.Enable = false;
            machinePro.Out_SpurtGlueControl.Enable = false;
            machinePro.Out_GlueChangeToSpurt.Enable = false;
            machinePro.Out_GlueChangeToSmall.Enable = false;

        }

        private void In_ManualButton_EnableEvent(IInput sender, InputEventArgs e)
        {
            if (isIntoIoTable == true)
            {
                if (IsSpurtGlue == true)
                {
                    machinePro.Out_PointGlueControl.Enable = false;
                    machinePro.Out_SpurtGlueControl.Enable = true;
                }
                else
                {
                    machinePro.Out_PointGlueControl.Enable = true;
                    machinePro.Out_SpurtGlueControl.Enable = false;
                }
            }
        }

        private void In_ManualButton_DisableEvent(IInput sender, InputEventArgs e)
        {
            if (isIntoIoTable == true)
            {
                machinePro.Out_PointGlueControl.Enable = false;
                machinePro.Out_SpurtGlueControl.Enable = false;
            }
        }

        /// <summary>
        /// 设置拍照的位置
        /// </summary>
        private void SetSnapPos()
        {
            try
            {
                projFile.SnapPosX = machinePro.XAxis.DPos;
                projFile.SnapPosY = machinePro.YAxis.DPos;
                projFile.SnapPosZ = machinePro.ZAxis.DPos;
            }
            catch (Exception)
            {

                throw;
            }
        }

        /// <summary>
        /// 设置标定位置
        /// </summary>
        public void SetCalibPos()
        {
            try
            {
                Calibration.CalibSnapMachX = machinePro.XAxis.DPos;
                Calibration.CalibSnapMachY = machinePro.YAxis.DPos;
                Calibration.CalibSnapMachZ = machinePro.ZAxis.DPos;
                Calibration.CalibSnapMachR = 0;
            }
            catch (Exception)
            {

                throw;
            }
        }

        private HTuple xs = new HTuple();
        private HTuple ys = new HTuple();
        private HTuple zs = new HTuple();
        public void SaveCalibXYPos(int index)
        {
            xs[index] = machinePro.XAxis.DPos;
            ys[index] = machinePro.YAxis.DPos;
            zs[index] = machinePro.ZAxis.DPos;
            HOperatorSet.WriteTuple(xs, CalibXPosPath);
            HOperatorSet.WriteTuple(ys, CalibYPosPath);
            HOperatorSet.WriteTuple(ys, CalibZPosPath);
        }

        public ControlMaster()
        {
            try
            {
                Calibration = new NinePointCalibByCamParamPos();
                MulitAxisMasterControl = new MulitAxisMaster();
                MulitAxisMasterControl.KeyUpControlEvent += MulitAxisMasterControl_KeyUpControlEvent;
                MulitAxisMasterControl.KeyDownControlEvent += MulitAxisMasterControl_KeyDownControlEvent;
                projFile = new ProjFile();
                Camera = new Camera_HKVision();
                machinePro = new MachinePro();
                //Camera = CameraIdBoundHelper.CreateCamera<Camera_HKVision>();
            }
            catch (Exception)
            {
                Dialog.ShowErrorDialog("总控制构造失败");
                ZrfTools.SystemShutDown();
                throw;
            }
        }

        private void MulitAxisMasterControl_KeyDownControlEvent(KeyBordControlEventArgs e)
        {
            Task.Run(() =>
            {
                lock (this)
                {
                    switch (e.KeyData)
                    {
                        case KeyBordEventMean.Left:
                            machinePro.XAxis.MoveJog(false);
                            break;
                        case KeyBordEventMean.Right:
                            machinePro.XAxis.MoveJog(true);
                            break;
                        case KeyBordEventMean.Up:
                            machinePro.ZAxis.MoveJog(false);
                            break;
                        case KeyBordEventMean.Down:
                            machinePro.ZAxis.MoveJog(true);
                            break;
                        case KeyBordEventMean.Back:
                            machinePro.YAxis.MoveJog(false);
                            break;
                        case KeyBordEventMean.Front:
                            machinePro.YAxis.MoveJog(true);
                            break;
                        case KeyBordEventMean.Foreward:
                            break;
                        case KeyBordEventMean.Reverse:
                            break;
                        case KeyBordEventMean.SpeedUp:
                            machinePro.Speed++;
                            break;
                        case KeyBordEventMean.SpeedDown:
                            machinePro.Speed--;
                            break;
                        case KeyBordEventMean.EmergentStop:
                            machinePro.EmergentStop();
                            break;
                        case KeyBordEventMean.Reset:
                            machinePro.AllAxisesHoming();
                            break;
                        default:
                            break;
                    }
                }
            });
        }

        private void MulitAxisMasterControl_KeyUpControlEvent(KeyBordControlEventArgs e)
        {
            switch (e.KeyData)
            {
                case KeyBordEventMean.Left:
                    machinePro.XAxis.DecelStop();
                    break;
                case KeyBordEventMean.Right:
                    machinePro.XAxis.DecelStop();
                    break;
                case KeyBordEventMean.Up:
                    machinePro.ZAxis.DecelStop();
                    break;
                case KeyBordEventMean.Down:
                    machinePro.ZAxis.DecelStop();
                    break;
                case KeyBordEventMean.Back:
                    machinePro.YAxis.DecelStop();
                    break;
                case KeyBordEventMean.Front:
                    machinePro.YAxis.DecelStop();
                    break;
                case KeyBordEventMean.Foreward:
                    break;
                case KeyBordEventMean.Reverse:
                    break;
                case KeyBordEventMean.SpeedUp:
                    break;
                case KeyBordEventMean.SpeedDown:
                    break;
                case KeyBordEventMean.EmergentStop:
                    break;
                case KeyBordEventMean.Reset:
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            try
            {
                Camera.CreateDevice();
                Camera.Open(GetFramModel.CallBackGetFram, TrigSource.Continuous);
                machinePro.Init();
                ((NinePointCalibByCamParamPos)Calibration).ReadCamParam(CamParamerPath);
                ((NinePointCalibByCamParamPos)Calibration).ReadCamPos(CamPosPath);
                ((NinePointCalibByCamParamPos)Calibration).ReadHomMat2d_WorldPlaneToMachCoord(HomMat2DPath);
                Task.Run(() =>
                {
                    //machinePro.AllAxisesHoming();
                });
                ReadSysParameter();
                machinePro.In_StartPauseButton.EnableEvent += In_StartPauseButton_EnableEvent;
                machinePro.In_ResetButton.EnableEvent += In_ResetButton_EnableEvent;
                machinePro.In_ManualButton.EnableEvent += In_ManualButton_EnableEvent;
                machinePro.In_ManualButton.DisableEvent += In_ManualButton_DisableEvent;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 执行工程的一系列工作
        /// </summary>
        //private void DoProjWork()
        //{
        //    if (isDoProjWork == true)
        //    {
        //        return;
        //    }
        //    isDoProjWork = true;
        //    Task.Run(() =>
        //    {
        //        CheckProj();
        //        GotoSnapPos();
        //        HImage newImg = Camera.SoftTrigGetOneFram();
        //        List<HXLD[]> allXldPaths = DoFindImgXldPath(newImg, XldPaths);
        //        StartProjWorkEvent?.Invoke(newImg, allXldPaths);
        //        List<MachCoord2dPath> allMachCoord2DPaths = ImgXldsTransFormMachPath(allXldPaths, XldPathInfos);
        //        for (int i = 0; i < allMachCoord2DPaths.Count; i++)
        //        {
        //            DoMachCoordPath(allMachCoord2DPaths[i]);
        //        }
        //        GotoSnapPos();
        //        isDoProjWork = false;
        //    });
        //}
        private void DoProjWork()
        {
            if (isDoProjWork == true)
            {
                return;
            }
            isDoProjWork = true;
            Task.Run(() =>
            {
                try
                {
                    CheckProj();
                    GotoSnapPos();
                    HImage newImg = Camera.SoftTrigGetOneFram();
                    List<List<XldPath>> allXldPaths = DoFindImgAllXldPaths(newImg, XldPaths);

                    List<XldPath> xldPaths = new List<XldPath>();
                    for (int i = 0; i < allXldPaths.Count; i++)
                    {
                        for (int j = 0; j < allXldPaths[i].Count; j++)
                        {
                            xldPaths.Add(allXldPaths[i][j]);
                        }
                    }
                    if (StartProjWorkEvent != null)//触发启动传图到窗口事件
                    {
                        StartProjWorkEvent.Invoke(newImg, xldPaths);
                    }
                    FindedProjAllXldPathsEvent?.Invoke(newImg, xldPaths);
                    if (xldPaths.Count == 0)
                    {
                        isDoProjWork = false;
                        return;
                    }
                    List<List<MachCoord2dPath>> allMachCoord2DPaths = ImgXldsTransFormMachPath(allXldPaths, XldPathInfos);
                    //拆分路径类型
                    List<List<MachCoord2dPath>> allMachSpurtGluePath = new List<List<MachCoord2dPath>>();
                    List<List<MachCoord2dPath>> allMachPointGluePath = new List<List<MachCoord2dPath>>();
                    //List<List<MachCoord2dPath>> allMachAvoidGluePath = new List<List<MachCoord2dPath>>();
                    for (int i = 0; i < allMachCoord2DPaths.Count; i++)
                    {
                        List<MachCoord2dPath> SingleBoardAllPaths = allMachCoord2DPaths[i];
                        List<MachCoord2dPath> SingleBoardSpurtPaths = new List<MachCoord2dPath>();
                        List<MachCoord2dPath> SingleBoardPointPaths = new List<MachCoord2dPath>();
                        //List<MachCoord2dPath> SingleBoardAvoidPaths = new List<MachCoord2dPath>();
                        for (int j = 0; j < SingleBoardAllPaths.Count; j++)
                        {
                            switch (SingleBoardAllPaths[j].Type)
                            {
                                //case PathType.None:
                                //    break;
                                case PathType.Glue:
                                    SingleBoardPointPaths.Add(SingleBoardAllPaths[j]);
                                    break;
                                case PathType.SpurtGlue:
                                    SingleBoardSpurtPaths.Add(SingleBoardAllPaths[j]);
                                    break;
                                //case PathType.AvoidPath:
                                //    SingleBoardAvoidPaths.Add(SingleBoardAllPaths[j]);
                                //    break;
                                default:
                                    break;
                            }
                        }
                        allMachSpurtGluePath.Add(SingleBoardSpurtPaths);
                        allMachPointGluePath.Add(SingleBoardPointPaths);
                        //allMachAvoidGluePath.Add(SingleBoardAvoidPaths);
                    }

                    //先喷全部的
                    for (int i = 0; i < allMachSpurtGluePath.Count; i++)
                    {
                        for (int j = 0; j < allMachSpurtGluePath[i].Count; j++)
                        {
                            if (machinePro.MotionStatus.IsEmergentStop == true)
                            {
                                isDoProjWork = false;
                                return;
                            }
                            DoMachCoordPath(allMachSpurtGluePath[i][j]);
                        }
                    }

                    //再点胶
                    for (int i = 0; i < allMachPointGluePath.Count; i++)
                    {
                        for (int j = 0; j < allMachPointGluePath[i].Count; j++)
                        {
                            if (machinePro.MotionStatus.IsEmergentStop == true)
                            {
                                isDoProjWork = false;
                                return;
                            }
                            DoMachCoordPath(allMachPointGluePath[i][j]);
                        }
                        _productionQuantity++;
                    }
                    machinePro.Out_GlueChangeToSmall.Enable = false;
                    machinePro.Out_GlueChangeToSpurt.Enable = false;
                    GotoSnapPos();
                    isDoProjWork = false;
                }
                catch (Exception e)
                {
                    isDoProjWork = false;
                    Dialog.ShowWarningDialog(e.Message);
                }
            });
        }

        private void PauseResumeProjWork()
        {
            if (machinePro.MotionStatus.IsPause == false)//暂停的话
            {
                machinePro.Pause();
            }
            else
            {
                machinePro.Resume();
            }
        }

        /// <summary>
        /// 执行单xldPath测试
        /// </summary>
        /// <param name="xldPath"></param>
        /// <param name="xldPathInfo"></param>
        /// <param name="needGlue"></param>
        //public void DoSingelXldPathTest(XldPath xldPath, XldPathInfo xldPathInfo, bool needGlue, out HImage newImg, out List<HXLD[]> allXldPaths)
        //{
        //    Camera.TrigSource = TrigSource.SoftTrig;
        //    Camera.StartGrabbing();
        //    GotoSnapPos();
        //    newImg = Camera.SoftTrigGetOneFram();
        //    allXldPaths = DoFindImgXldPath(newImg, new List<XldPath>() { xldPath });
        //    List<MachCoord2dPath> allMachCoord2DPaths = ImgXldsTransFormMachPath(allXldPaths, new List<XldPathInfo>() { xldPathInfo });
        //    Task.Run(() =>
        //    {
        //        for (int i = 0; i < allMachCoord2DPaths.Count; i++)
        //        {
        //            DoMachCoordPath(allMachCoord2DPaths[i], needGlue);
        //        }
        //        GotoSnapPos();
        //    });
        //}

        /// <summary>
        /// 执行单xldPath测试
        /// </summary>
        /// <param name="xldPath"></param>
        /// <param name="xldPathInfo"></param>
        /// <param name="needGlue"></param>
        public void DoSingelXldPathTest(XldPath xldPath, XldPathInfo xldPathInfo, bool needGlue, out HImage newImg, out List<XldPath> allXldPaths)
        {
            Camera.TrigSource = TrigSource.SoftTrig;
            Camera.StartGrabbing();
            GotoSnapPos();
            if (machinePro.MotionStatus.IsEmergentStop == true)
            {
                newImg = new HImage();
                allXldPaths = new List<XldPath>();
                return;
            }
            newImg = Camera.SoftTrigGetOneFram();
            List<List<XldPath>> listXldPaths = DoFindImgAllXldPaths(newImg, new List<XldPath>() { xldPath });


            allXldPaths = new List<XldPath>();
            for (int i = 0; i < listXldPaths.Count; i++)
            {
                for (int j = 0; j < listXldPaths[i].Count; j++)
                {
                    allXldPaths.Add(listXldPaths[i][j]);
                }
            }

            List<List<MachCoord2dPath>> allMachCoord2DPaths = ImgXldsTransFormMachPath(listXldPaths, new List<XldPathInfo>() { xldPathInfo });
            if (machinePro.MotionStatus.IsEmergentStop == true)
            {
                return;
            }
            Task.Run(() =>
            {
                for (int i = 0; i < allMachCoord2DPaths.Count; i++)
                {
                    for (int j = 0; j < allMachCoord2DPaths[i].Count; j++)
                    {
                        if (machinePro.MotionStatus.IsEmergentStop == true)
                        {
                            return;
                        }
                        DoMachCoordPath(allMachCoord2DPaths[i][j], needGlue);
                    }
                }
                GotoSnapPos();
            });
        }

        public void CancelGluingTest()
        {
            if (machinePro.IsRunMark == true)
            {
                Task.Run(() =>
                {
                    machinePro.EmergentStop();
                    Thread.Sleep(500);
                    machinePro.ResetEmergentStop();
                });
            }
        }

        /// <summary>
        /// 图像XLD转成实际机械坐标
        /// </summary>
        /// <param name="allXlds"></param>
        /// <returns></returns>
        private List<MachCoord2dPath> ImgXldsTransFormMachPath(List<HXLD[]> allXlds, List<XldPathInfo> xldPathInfos)
        {
            List<MachCoord2dPath> allMachCoord2dPaths = new List<MachCoord2dPath>();
            for (int i = 0; i < allXlds.Count; i++)
            {
                for (int j = 0; j < allXlds[i].Length; j++)
                {
                    MachCoord2dPath machCoord2DPath = new MachCoord2dPath(xldPathInfos[j], allXlds[i][j], Calibration);
                    allMachCoord2dPaths.Add(machCoord2DPath);
                }
            }
            return allMachCoord2dPaths;
        }

        private List<List<MachCoord2dPath>> ImgXldsTransFormMachPath(List<List<XldPath>> allXldPaths, List<XldPathInfo> xldPathInfos)
        {
            if (xldPathInfos.Count != allXldPaths[0].Count)
            {
                throw new Exception("路径数量和info不匹配");
            }
            List<List<MachCoord2dPath>> allMachCoord2dPaths = new List<List<MachCoord2dPath>>();
            for (int i = 0; i < allXldPaths.Count; i++)
            {
                List<MachCoord2dPath> machCoord2dPaths = new List<MachCoord2dPath>();
                for (int j = 0; j < allXldPaths[i].Count; j++)
                {
                    MachCoord2dPath machCoord2DPath = new MachCoord2dPath(xldPathInfos[j], allXldPaths[i][j], Calibration);
                    machCoord2dPaths.Add(machCoord2DPath);
                }
                allMachCoord2dPaths.Add(machCoord2dPaths);
            }
            return allMachCoord2dPaths;
        }

        /// <summary>
        /// 检查工程完整可用性
        /// </summary>
        private void CheckProj()
        {
            if (XldPathInfos.Count == 0)
            {
                throw new Exception("点胶路径为空");
            }
            if (Calibration.IsWorkability == false)
            {
                throw new Exception("标定不可用");
            }
            if (ShapeMatching.ModelEnable == false)
            {
                throw new Exception("找图模板不可用");
            }
        }

        /// <summary>
        /// 执行找全图所有的xlds
        /// </summary>
        /// <param name="newCaptureImg"></param>
        /// <returns></returns>
        private List<HXLD[]> DoFindImgXldPath(HImage newCaptureImg, List<XldPath> xldPaths)
        {
            HXLD[] xlds = GetProjAllXldPath(xldPaths);
            return ShapeMatching.FindAllXlds(xlds, newCaptureImg);
        }

        /// <summary>
        /// 找全图的xldPaths
        /// </summary>
        /// <param name="newCaptureImg"></param>
        /// <param name="xldPaths"></param>
        /// <returns></returns>
        private List<List<XldPath>> DoFindImgAllXldPaths(HImage newCaptureImg, List<XldPath> xldPaths)
        {
            return ShapeMatching.FindAllXldPaths(xldPaths, newCaptureImg);
        }

        /// <summary>
        /// 获取工程的所有xlds
        /// </summary>
        /// <returns></returns>
        private HXLD[] GetProjAllXldPath(List<XldPath> xldPaths)
        {
            List<HXLD> result = new List<HXLD>();
            for (int i = 0; i < xldPaths.Count; i++)
            {
                result.Add(xldPaths[i].XLD);
            }
            return result.ToArray();
        }

        /// <summary>
        /// 去拍照位
        /// </summary>
        public void GotoSnapPos()
        {
            // machinePro.GotoSnapPos(SnapPosX, SnapPosY, SnapPosZ);
            machinePro.GotoSnapPos();
        }

        public void GotoCalibPos()
        {
            //machinePro.GotoSnapPos((float)Calibration.CalibSnapMachX, (float)Calibration.CalibSnapMachY, (float)Calibration.CalibSnapMachZ);
            machinePro.GotoSnapPos();
        }

        /// <summary>
        /// 执行点胶路径
        /// </summary>
        /// <param name="machPath"></param>
        /// <param name="needOutGlue"></param>
        public void DoMachCoordPath(MachCoord2dPath machPath, bool needOutGlue = true)
        {
            machinePro.DoMachCoordPath(machPath, needOutGlue);
        }

        /// <summary>
        /// 机器急停
        /// </summary>
        public void MachineEmergentStop()
        {
            machinePro.EmergentStop();
        }

        /// <summary>
        /// 机器解除急停
        /// </summary>
        public void MachineResetEmergentStop()
        {
            machinePro.ResetEmergentStop();
        }

        /// <summary>
        /// 关闭
        /// </summary>
        public void Close()
        {
            Camera.Close();
            machinePro.Close();
            SaveSysParameter();
        }
    }
    /// <summary>
    /// 窗口上xldPath的附加信息
    /// </summary>
    [Serializable]
    public class XldPathInfo
    {
        /// <summary>
        /// 屏蔽标志
        /// </summary>
        public bool Shield { get; internal set; }
        /// <summary>
        /// 需要出胶？
        /// </summary>
        //public bool NeedGlue { get; internal set; }
        /// <summary>
        /// 路径类型
        /// </summary>
        public PathType Type { get; internal set; }
        /// <summary>
        /// 路径颜色
        /// </summary>
        public PathColor Color { get; internal set; }
        /// <summary>
        /// 起始点延时出胶时间 单位：秒
        /// </summary>
        public double Delay_DelayToOutGlue { get; internal set; }
        /// <summary>
        /// 起始点持续出胶时间 单位：秒
        /// </summary>
        public double Delay_OutGlueToStartMove { get; internal set; }
        /// <summary>
        /// 结束出胶延时时间 单位：秒
        /// </summary>
        public double Delay_StopGlueDelayTime { get; internal set; }
        /// <summary>
        /// 点胶速度  单位：mm/s
        /// </summary>
        public double Speed { get; internal set; }
        /// <summary>
        /// 离工作面高度 单位：mm
        /// </summary>
        public double PlaneHeight { get; internal set; }
        /// <summary>
        /// Z轴贴到板面的zpos
        /// </summary>
        public double ZPlanePos { get; internal set; }
        /// <summary>
        /// 拍照位置X
        /// </summary>
        //public double SnapPosX { get; internal set; }
        /// <summary>
        /// 拍照位置Y
        /// </summary>
        //public double SnapPosY { get; internal set; }
        /// <summary>
        /// 拍照位置Z
        /// </summary>
        //public double SnapPosZ { get; internal set; }
        /// <summary>
        /// 偏差X
        /// </summary>
        public double MachCoordDeviationX { get; internal set; }
        /// <summary>
        /// 偏差Y
        /// </summary>
        public double MachCoordDeviationY { get; internal set; }
    }

    /// <summary>
    /// 机械坐标图像路径
    /// </summary>
    public class MachCoord2dPath : XldPathInfo
    {
        /// <summary>
        /// 机械坐标2D路径
        /// </summary>
        /// <param name="imageXldPathInfo"></param>
        /// <param name="xldPath"></param>
        /// <param name="calibration2D"></param>
        public MachCoord2dPath(XldPathInfo xldPathInfo, HXLD xld, ICalibration2D calibration2D)
        {
            //子类赋值
            var parentProperties = xldPathInfo.GetType().GetProperties();
            foreach (var parentProperty in parentProperties)
            {
                var thisProperty = this.GetType().GetProperty(parentProperty.Name, parentProperty.PropertyType);
                var value = parentProperty.GetValue(xldPathInfo);
                if (thisProperty != null && value != null && thisProperty.CanWrite)
                {
                    thisProperty.SetValue(this, value);
                }
            }
            calibration2D.ImgXldToMachCoordPoints(xld, out double[] Xs, out double[] Ys);
            //double offsetX = xldPathInfo.SnapPosX - calibration2D.CalibSnapMachX + xldPathInfo.MachCoordDeviationX;
            //double offsetY = xldPathInfo.SnapPosY - calibration2D.CalibSnapMachY + xldPathInfo.MachCoordDeviationY;
            double offsetX = xldPathInfo.MachCoordDeviationX;
            double offsetY = xldPathInfo.MachCoordDeviationY;
            xPoses = Xs.Select(v => v + offsetX).ToArray();
            yPoses = Ys.Select(v => v + offsetY).ToArray();
            zPoses = new double[yPoses.Length];
            double zWorkPos = xldPathInfo.ZPlanePos - PlaneHeight;
            Array.Fill(zPoses, zWorkPos);
        }
        public MachCoord2dPath(XldPathInfo xldPathInfo, XldPath path, ICalibration2D calibration2D)
        {
            //子类赋值
            var parentProperties = xldPathInfo.GetType().GetProperties();
            foreach (var parentProperty in parentProperties)
            {
                var thisProperty = this.GetType().GetProperty(parentProperty.Name, parentProperty.PropertyType);
                var value = parentProperty.GetValue(xldPathInfo);
                if (thisProperty != null && value != null && thisProperty.CanWrite)
                {
                    thisProperty.SetValue(this, value);
                }
            }
            calibration2D.ImgXldToMachCoordPoints(path.XLD, out double[] Xs, out double[] Ys);
            //double offsetX = xldPathInfo.SnapPosX - calibration2D.CalibSnapMachX + xldPathInfo.MachCoordDeviationX;
            //double offsetY = xldPathInfo.SnapPosY - calibration2D.CalibSnapMachY + xldPathInfo.MachCoordDeviationY;
            double offsetX = xldPathInfo.MachCoordDeviationX;
            double offsetY = xldPathInfo.MachCoordDeviationY;

            xPoses = Xs.Select(v => v + offsetX).ToArray();
            yPoses = Ys.Select(v => v + offsetY).ToArray();
            zPoses = new double[yPoses.Length];
            double zWorkPos = xldPathInfo.ZPlanePos - PlaneHeight;
            Array.Fill(zPoses, zWorkPos);
        }

        public double[] XPoses { get { return xPoses; } }
        public double[] YPoses { get { return yPoses; } }
        public double[] ZPoses { get { return zPoses; } }
        private double[] xPoses;
        private double[] yPoses;
        private double[] zPoses;
    }

    public enum PathType
    {
        None = 0,
        Glue = 1,
        SpurtGlue = 2,
        AvoidPath = 3,
    }

    public enum PathColor
    {
        none,
        blue,
        yellow,
        magenta,
        green,
        gray,
    }

    public delegate void StartProjWorkEventHandler(HImage newImg, List<XldPath> allXldPaths);

    public delegate void FindedProjAllXldPathsEventHandler(HImage newImg, List<XldPath> xldPaths);
}